﻿#region Using
using System;
using System.IO;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;
using Microsoft.Xna.Framework.Net;
using Microsoft.Xna.Framework.Storage;
using JigLibX.Physics;
using JigLibX.Geometry;
using JigLibX.Collision;
using JigLibX.Math;
#endregion Using

namespace LloydGame
{
    public class SparkParticleSystem : ParticleSystem
    {
        protected int m_gapToPrevPosition;

        #region Constructor
        public SparkParticleSystem(Game p_game, int p_nrParticles, Vector3 p_position, int p_gapToPrevPosition, bool p_respawnParticles)
            : base(p_game, p_nrParticles, p_position, p_respawnParticles)
        {
            m_gapToPrevPosition = p_gapToPrevPosition;

            m_particleTexture = Game.Content.Load<Texture2D>("Textures\\Particle_Spark");
        }
        #endregion

        #region Update
        protected override void updateParticle(int p_nr, GameTime p_gameTime)
        {
            float dt = ((float)p_gameTime.ElapsedRealTime.Milliseconds) / 1000.0f;

            if (m_particles[p_nr].prevPositions.Count >= m_gapToPrevPosition)
            {
                m_particles[p_nr].prevPosition = m_particles[p_nr].prevPositions.Dequeue();
            }

            m_particles[p_nr].prevPositions.Enqueue(m_particles[p_nr].position);

            m_particles[p_nr].position += m_particles[p_nr].velocity * dt;

            m_particles[p_nr].velocity.Y -= 30f * dt; // lol gravity because of fucked up scales

            m_particles[p_nr].energy -= dt;
        }

        protected override void setupShape(int p_nr)
        {
            // get current and previous position in view space
            Vector3 particleViewPos = Vector3.Transform(m_particles[p_nr].position, ((Game1)Game).camera.view);
            Vector3 particleViewPosPrev = Vector3.Transform(m_particles[p_nr].prevPosition, ((Game1)Game).camera.view);

            // calculate the direction of the particle
            Vector3 particleDirection = particleViewPos - particleViewPosPrev;
            particleDirection.Normalize();

            // calculate the screen space bidirection(?) of the particle
            Vector2 particleScreenDirection = new Vector2(particleDirection.X, particleDirection.Y);
            particleScreenDirection.Normalize();

            Matrix rotZ = Matrix.CreateRotationZ((float)Math.PI/2);

            Vector3 particleBiDirection = new Vector3(Vector2.Transform(particleScreenDirection, rotZ), 0);
            particleBiDirection.Normalize();

            // scale the direction and bidirection by the particles size
            particleDirection *= m_particles[p_nr].size;
            particleBiDirection *= m_particles[p_nr].size;

            // setup shape vertices in view space
            m_shapes[p_nr * 4].Position =
                -particleDirection + particleBiDirection + particleViewPosPrev;

            m_shapes[p_nr * 4 + 1].Position =
                particleDirection + particleBiDirection + particleViewPos;

            m_shapes[p_nr * 4 + 2].Position =
                particleDirection - particleBiDirection + particleViewPos;

            m_shapes[p_nr * 4 + 3].Position =
                -particleDirection - particleBiDirection + particleViewPosPrev;
        }

        protected override void setParticleDefaults(Particle p_particle, Vector3 p_particleDir)
        {
            p_particle.position = new Vector3(m_spawnPosition.X, m_spawnPosition.Y, m_spawnPosition.Z);
            p_particle.prevPosition = p_particle.position;

            float x = (float)((Game1)Game).random.NextDouble() - 0.5f;
            float y = (float)((Game1)Game).random.NextDouble() - 0.5f;
            float z = (float)((Game1)Game).random.NextDouble() - 0.5f;
 
            Vector3 v = new Vector3(x, y, z) * 6 + p_particleDir;

            p_particle.velocity = v;

            p_particle.energy = 2;
            p_particle.size = 0.02f;

            p_particle.prevPositions.Clear();
        }
        #endregion
    }
}
